package com.cloud.rou.common.executor;


import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.*;

/**
 * <p></p>
 *
 * @author GaoShuangWen
 * @since 2019-10-31 21:39
 */

public abstract class AbstractExecutor<T> implements Executor<T> {

    private ListeningExecutorService guavaExecutor = MoreExecutors
            .listeningDecorator(Executors.newSingleThreadExecutor());


    public AbstractExecutor() {
        this(null);
    }

    public AbstractExecutor(ExecutorService executorService) {
        this.guavaExecutor = executorService == null ? guavaExecutorFunc(Executors.newSingleThreadExecutor()) : guavaExecutorFunc(executorService);
    }

    private ListeningExecutorService guavaExecutorFunc(ExecutorService executorService) {
        return MoreExecutors
                .listeningDecorator(executorService);
    }

    @Override
    public T execute(Object... request) {
        return doExecute(request);
    }

    @Override
    public ExecutorFuture<T> asyncExecute(Object... request) {

        ListenableFuture<T> listenableFuture = guavaExecutor
                .submit(new Callable<T>() {
                    @Override
                    public T call() throws Exception {
                        return doExecute(request);
                    }
                });
        return  new DefaultListenableFuture<>(listenableFuture);
    }


    public abstract T doExecute(Object... request);


}
